// Copyright (c) Appeon
// The following has been modified by Appeon under compliance with the Apache 2.0 license from the original work

// Copyright(c) 2002-2019, Npgsql
// Permission to use, copy, modify, and distribute this software and its
// documentation for any purpose, without fee, and without a written agreement
// is hereby granted, provided that the above copyright notice and this
// paragraph and the following two paragraphs appear in all copies.
//
// IN NO EVENT SHALL NPGSQL BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// Npgsql HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// NPGSQL SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE.THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND Npgsql
// HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
// OR MODIFICATIONS.

using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using JetBrains.Annotations;

namespace SnapObjects.Data.PostgreSql
{
    public class PostgreSqlHstoreTypeMapping : TypeMapping
    {
        public PostgreSqlHstoreTypeMapping(
            [NotNull] string dbTypeName, 
            [NotNull] Type clrType,
            [CanBeNull] DbType? dbType = null, 
            bool unicode = false, 
            int? size = null) 
            : base(dbTypeName, clrType, dbType, unicode, size)
        {
        }

        public override TypeMapping Clone([NotNull] string dbTypeName, int? size)
        {
            return new PostgreSqlHstoreTypeMapping(this.DbTypeName, this.ClrType, this.DbType, this.IsUnicode, this.Size);
        }

        protected override string GenerateNonNullSqlLiteral(object value)
        {
            var sb = new StringBuilder("HSTORE '");
            foreach (var kv in (Dictionary<string, string>)value)
            {
                sb.Append('"');
                sb.Append(kv.Key);   // TODO: Escape
                sb.Append("\"=>");
                if (kv.Value == null)
                {
                    sb.Append("NULL");
                }
                else
                {
                    sb.Append('"');
                    sb.Append(kv.Value);   // TODO: Escape
                    sb.Append("\",");
                }
            }

            sb.Remove(sb.Length - 1, 1);

            sb.Append('\'');
            return sb.ToString();
        }
    }
}
